Match QEMU audio rates to selected Mac devices - #283
Merged
Merged
Conversation
QEMU's audiodev defaults to a 44100 Hz mixer regardless of the host output device. When the Mac's default output device runs at any other rate, the guest's PCM stream is drained at the wrong speed and playback drifts. At 48000 Hz, the macOS built-in default, a 20.000 s clip plays in about 19.0 s. Query CoreAudio for the default output device's nominal rate and pass it as out.frequency/in.frequency so the mixer and the device agree. Fall back to 48000 when the query cannot answer. Measured with a 20.000 s tone played by pw-play in the guest and timed from the host over an SSH forward, so the guest clock is outside the measurement path (8-10 runs per condition): device 48000, before: 19.033 s / 19.090 s (about 4.8% fast) device 48000, after: 20.158 s (sd 0.019) device 44100, before: 20.013 s / 19.867 s device 44100, after: 20.161 s (sd 0.017) Both rates now land on the same figure, so playback speed no longer depends on the host device rate. The residual 0.16 s is constant pw-play startup and is present in every configuration.
The launcher now passes the Mac output device's rate to the audiodev, so the exact -audiodev line the test pinned no longer matched. Give the test a system_profiler shim that reports a 44100 Hz default output device and expect out.frequency and in.frequency at that rate, which also checks the detection instead of the 48000 fallback.
digital-brew
pushed a commit
to digital-brew/try-omarchy
that referenced
this pull request
Sep 29, 2026
QEMU's audiodev opens its mixer at 44100 Hz regardless of the Mac's output device. With the device at macOS's default 48000 Hz the guest's PCM stream is drained at the wrong speed and every app plays about 5 percent fast and sharp. Read the default output device's nominal rate from CoreAudio through system_profiler and pass it as out.frequency and in.frequency, falling back to 48000 when the query cannot answer. From omacom#283. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018W8fhTegW8d16zpAjRpsT9
digital-brew
pushed a commit
to digital-brew/try-omarchy
that referenced
this pull request
Sep 29, 2026
QEMU's audiodev opens its mixer at 44100 Hz regardless of the Mac's output device. With the device at macOS's default 48000 Hz the guest's PCM stream is drained at the wrong speed and every app plays about 5 percent fast and sharp. Read the default output device's nominal rate from CoreAudio through system_profiler and pass it as out.frequency and in.frequency, falling back to 48000 when the query cannot answer. From omacom#283. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018W8fhTegW8d16zpAjRpsT9
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed and why
Addresses #265: guest audio is reported to play too fast when the host output uses a different rate from QEMU's default mixer.
At launch, query CoreAudio through the bundled native helper and set QEMU's input and output frequencies independently. Each query follows the effective SDL device selected in Omarchy, including duplicate-name suffixes, and uses that direction's Mac default when a saved device is disconnected. Unavailable or invalid rates fall back to 48000 Hz independently. No new dependencies or runtime pins.
This is a launch-time mitigation. The underlying timing or resampling fault has not been isolated, and rates remain fixed until the VM restarts. Changing a device or its rate during a session can require a restart.
Testing
make test-shell-qemu-memory-contract: passed, including the Swift tests and the launcher contract. Coverage includes selected routes, duplicate SDL names, direction-specific defaults, disconnected-device fallback, rate validation, and independent query failures.make test: passed on macOS, including a rerun after resolving conflicts with current main. Staged-QEMU lock inheritance was skipped because the staged runtime binary is absent.bash -n macos/run-qemu-gpu.sh macos/Tests/qemu-memory-contract.test.shandgit diff --check: passed.Original author measurements on an M3 MacBook Air running macOS 15.6 used a 20.000-second stereo tone, host-side monotonic timing over SSH, and 8–10 runs per condition:
These results were reported by the original author and were not independently reproduced here. Detection at 88200 and 96000 Hz was reported, but playback validation was limited to 44100 and 48000 Hz. The author also reported residual drift at 96000 Hz on an unpatched build even with matched rates. Earlier issue measurements saying a matched 48000 Hz mixer still drifted remain to be reconciled with the later results.